package com.pt.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.pt.common.util.BencodeUtil;
import com.pt.entity.Peer;
import com.pt.entity.User;
import com.pt.entity.Torrent;
import com.pt.service.PeerService;
import com.pt.service.TorrentService;
import com.pt.service.UserService;
import com.pt.common.constant.TorrentConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.DecoderException;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.net.URLDecoder;
import java.util.Base64;

@Slf4j
@RestController
@RequestMapping("/api")
@CrossOrigin(origins = "*", allowedHeaders = "*")
public class TrackerController {
    
    @Autowired
    private PeerService peerService;
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private TorrentService torrentService;
    
    @GetMapping("/announce")
    public ResponseEntity<byte[]> announce(
            @RequestParam String passkey,
            @RequestParam String info_hash,
            @RequestParam String peer_id,
            @RequestParam Integer port,
            @RequestParam Long uploaded,
            @RequestParam Long downloaded,
            @RequestParam Long left,
            @RequestParam(required = false) String event,
            @RequestParam(defaultValue = "50") Integer numwant,
            @RequestParam(defaultValue = "1") Integer compact,
            @RequestParam(required = false) Integer no_peer_id,
            HttpServletRequest request) {
        String queryString = request.getQueryString();
        System.out.println("原始查询字符串: " + queryString);

        // 查找info_hash参数
        String infoHashParam = null;
        if (queryString != null) {
            String[] params = queryString.split("&");
            for (String param : params) {
                if (param.startsWith("info_hash=")) {
                    infoHashParam = param.substring("info_hash=".length());
                    break;
                }
            }
        }

        info_hash = infoHashParam;
        System.out.println("11111URL编码的info_hash: " + infoHashParam);
        System.out.println("11111URL参数的info_hash: " + info_hash);


        try {
            log.info("\n=== TRACKER ANNOUNCE 请求到达 ===");
            log.info("时间: {}", new Date());
            log.info("请求参数 - passkey: {}, uploaded: {}, downloaded: {}, left: {}, event: {}", 
                    passkey, uploaded, downloaded, left, event);
            
            // 1. 验证用户
            User user = getUserByPasskey(passkey);
            if (user == null) {
                return buildErrorResponse("Invalid passkey");
            }
            
            // 2. 处理info_hash
            String finalInfoHash = processInfoHash(info_hash);
            if (finalInfoHash == null) {
                return buildErrorResponse("Invalid info_hash");
            }
            
            // 3. 查询种子是否存在
            QueryWrapper<Torrent> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("info_hash", finalInfoHash)
                    .eq("status", TorrentConstant.STATUS_NORMAL)
                    .eq("is_deleted", false);
            
            Torrent torrent = torrentService.getOne(queryWrapper);
            if (torrent == null) {
                log.warn("种子不存在或状态异常 - infoHash: {}", finalInfoHash);
                return buildErrorResponse("Torrent not found");
            }
            
            // 4. 获取客户端IP
            String clientIp = getClientIp(request);
            log.info("客户端IP: {}", clientIp);
            
            // 5. 处理事件
            boolean isSeeder = left == 0;
            if ("completed".equals(event)) {
                // 完成下载事件
                torrentService.incrementDownloadCount(torrent.getId());
                isSeeder = true;
            } else if ("stopped".equals(event)) {
                // 停止事件，移除peer
                peerService.removePeer(finalInfoHash, user.getId());
                // 返回空的peer列表
                return buildSuccessResponse(0, 0, Collections.emptyList(), compact == 1);
            }
            
            // 6. 更新用户统计数据
            userService.updateUserStats(user.getId(), uploaded, downloaded);
            
            // 7. 更新peer状态
            peerService.updatePeerStatus(finalInfoHash, user.getId(), clientIp, port, 
                    uploaded, downloaded, left, event, request.getHeader("User-Agent"));
            
            // 8. 获取peer统计
            int seeders = peerService.countSeeders(finalInfoHash);
            int leechers = peerService.countLeechers(finalInfoHash);
            
            // 9. 获取peer列表（排除当前用户）
            List<Peer> peers = peerService.getPeers(finalInfoHash, user.getId(), numwant);
            
            // 10. 构建并返回响应
            return buildSuccessResponse(seeders, leechers, peers, compact == 1);
            
        } catch (Exception e) {
            log.error("Tracker announce处理失败", e);
            return buildErrorResponse("Internal server error");
        }
    }
    
    private ResponseEntity<byte[]> buildSuccessResponse(int seeders, int leechers, List<Peer> peers, boolean isCompact) {
        try {
            Map<String, Object> response = new HashMap<>();
            response.put("interval", TorrentConstant.ANNOUNCE_INTERVAL);
            response.put("min interval", TorrentConstant.MIN_ANNOUNCE_INTERVAL);
            response.put("complete", seeders);
            response.put("incomplete", leechers);
            
            if (isCompact) {
                // 紧凑模式：每个peer使用6字节（4字节IP + 2字节端口）
                ByteArrayOutputStream peerData = new ByteArrayOutputStream();
                for (Peer peer : peers) {
                    // 转换IP地址为字节
                    String[] ipParts = peer.getIp().split("\\.");
                    if (ipParts.length == 4) {
                        for (String part : ipParts) {
                            peerData.write(Integer.parseInt(part));
                        }
                        // 添加端口（大端序）
                        peerData.write((peer.getPort() >> 8) & 0xFF);
                        peerData.write(peer.getPort() & 0xFF);
                    }
                }
                response.put("peers", peerData.toByteArray());
            } else {
                // 字典模式
                List<Map<String, Object>> peerList = new ArrayList<>();
                for (Peer peer : peers) {
                    Map<String, Object> peerInfo = new HashMap<>();
                    peerInfo.put("ip", peer.getIp());
                    peerInfo.put("port", peer.getPort());
                    if (peer.getPeerId() != null) {
                        peerInfo.put("peer id", peer.getPeerId());
                    }
                    peerList.add(peerInfo);
                }
                response.put("peers", peerList);
            }
            
            // 编码为bencode格式
            byte[] bencoded = BencodeUtil.encodeTorrent(response);
            
            return ResponseEntity.ok()
                    .contentType(MediaType.APPLICATION_OCTET_STREAM)
                    .body(bencoded);
            
        } catch (Exception e) {
            log.error("构建响应失败", e);
            return buildErrorResponse("Failed to build response");
        }
    }
    
    private ResponseEntity<byte[]> buildErrorResponse(String message) {
        Map<String, Object> response = new HashMap<>();
        response.put("failure reason", message);
        
        try {
            byte[] bencoded = BencodeUtil.encodeTorrent(response);
            return ResponseEntity.badRequest()
                    .contentType(MediaType.APPLICATION_OCTET_STREAM)
                    .body(bencoded);
        } catch (Exception e) {
            log.error("构建错误响应失败", e);
            String fallback = "d14:failure reason" + message.length() + ":" + message + "e";
            return ResponseEntity.badRequest()
                    .contentType(MediaType.APPLICATION_OCTET_STREAM)
                    .body(fallback.getBytes(StandardCharsets.ISO_8859_1));
        }
    }
    
    private String getClientIp(HttpServletRequest request) {
        // 优先使用X-Real-IP
        String ip = request.getHeader("X-Real-IP");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Forwarded-For");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        
        // 处理多个IP的情况（取第一个）
        if (ip != null && ip.contains(",")) {
            ip = ip.split(",")[0].trim();
        }
        
        // 处理IPv6
        if ("0:0:0:0:0:0:0:1".equals(ip)) {
            ip = "127.0.0.1";
        }
        
        return ip;
    }
    
    private User getUserByPasskey(String passkey) {
        if (passkey == null || passkey.isEmpty()) {
            return null;
        }
        return userService.lambdaQuery()
                .eq(User::getPasskey, passkey)
                .eq(User::getStatus, 1)
                .one();
    }
    
    @GetMapping(value = "/scrape")
    public ResponseEntity<byte[]> scrape(
            @RequestParam(required = false) String info_hash,
            @RequestParam(required = false) String passkey) {
        
        try {
            // 验证用户（如果提供了passkey）
            if (passkey != null) {
                User user = getUserByPasskey(passkey);
                if (user == null) {
                    return buildErrorResponse("Invalid passkey");
                }
            }
            
            Map<String, Object> response = new HashMap<>();
            Map<String, Object> files = new HashMap<>();
            
            if (info_hash != null) {
                // 单个种子的scrape
                String finalInfoHash = processInfoHash(info_hash);
                if (finalInfoHash != null) {
                    Torrent torrent = torrentService.lambdaQuery()
                            .eq(Torrent::getInfoHash, finalInfoHash)
                            .eq(Torrent::getStatus, TorrentConstant.STATUS_NORMAL)
                            .eq(Torrent::getIsDeleted, false)
                            .one();
                    
                    if (torrent != null) {
                        Map<String, Object> stats = new HashMap<>();
                        stats.put("complete", torrent.getSeeders());
                        stats.put("downloaded", torrent.getFinished());
                        stats.put("incomplete", torrent.getLeechers());
                        files.put(info_hash, stats);
                    }
                }
            } else {
                // 全部种子的scrape（限制数量）
                List<Torrent> torrents = torrentService.lambdaQuery()
                        .eq(Torrent::getStatus, TorrentConstant.STATUS_NORMAL)
                        .eq(Torrent::getIsDeleted, false)
                        .last("LIMIT 100")
                        .list();
                
                for (Torrent torrent : torrents) {
                    Map<String, Object> stats = new HashMap<>();
                    stats.put("complete", torrent.getSeeders());
                    stats.put("downloaded", torrent.getFinished());
                    stats.put("incomplete", torrent.getLeechers());
                    files.put(torrent.getInfoHash(), stats);
                }
            }
            
            response.put("files", files);
            
            // 编码为bencode格式
            byte[] bencoded = BencodeUtil.encodeTorrent(response);
            return ResponseEntity.ok()
                    .contentType(MediaType.APPLICATION_OCTET_STREAM)
                    .body(bencoded);
            
        } catch (Exception e) {
            log.error("Scrape请求处理失败", e);
            return buildErrorResponse("Internal server error");
        }
    }

    /**
     * 处理info_hash，支持多种编码格式
     * @param infoHash 原始info_hash
     * @return 处理后的info_hash，如果无法处理则返回null
     */
    private String processInfoHash(String infoHash) {
        log.info("处理info_hash: {}", infoHash);
        
        try {
            String ISOdecoded = java.net.URLDecoder.decode(infoHash, "ISO-8859-1");
            log.info("ISOURL解码后: {}", ISOdecoded);

            byte[] mybytes = ISOdecoded.getBytes("ISO-8859-1");
            StringBuilder sb = new StringBuilder();
            for (byte b : mybytes) {
                sb.append(String.format("%02x", b & 0xFF));
            }
            System.out.println("sb = " + sb.toString());
            return sb.toString();
            
        } catch (Exception e) {
            log.error("处理info_hash时发生错误", e);
            return null;
        }
    }
    

} 